package com.dzp.simpleSyslogServer.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class CommonUtil {
	public static String PATTERN_FULL = "yyyy-MM-dd HH:mm:ss";
	public static String PATTERN_FULL_TRANSNO = "yyyyMMddHHmmss";
	public static String PATTERN_SHORT = "yyyy-MM-dd";
	public static String TempFilePath = "/home/temp";
	private static Logger logger = LoggerFactory.getLogger(CommonUtil.class);

	// 返回流水号，跟踪日志
	public static String getTransNo(String transNoPrefix) {
		return transNoPrefix + "_" + getTimeStr() + "_" + RandomStringUtils.randomAlphanumeric(6);
	}

	public static String getDateStr() {
		return DateFormatUtils.format(new Date(), CommonUtil.PATTERN_SHORT);
	}

	public static String getUTCDateStr(Date date) {
		return DateFormatUtils.format(date, "yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"));
	}

	public static String getTimeStr() {
		return DateFormatUtils.format(new Date(), CommonUtil.PATTERN_FULL_TRANSNO);
	}

	public static String getFullTimeStr() {
		return DateFormatUtils.format(new Date(), CommonUtil.PATTERN_FULL);
	}

	// 日志处理方法
	public static String getExceptionTrace(Throwable e) {
		if (e != null) {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			return sw.toString();
		}
		return null;
	}

	/**
	 * 通用记录日志
	 * 
	 * @param msg
	 * @param clazz
	 * @param e
	 */
	public static void logger(String msg, Class<?> clazz) {
		logger(msg, clazz, null);
	}

	public static void logger(String msg, Class<?> clazz, Throwable e) {
		String loggerName = clazz.getName();
		String loggerTime = getFullTimeStr();
		if (e == null) {
			logger.info("--logger--loggerName = {} ; msg = {} ; loggerTime = {}", loggerName, msg, loggerTime);
		} else {
			logger.error("--logger--loggerName = {} ; msg = {} ; loggerTime = {} ; ExceptionTrace =>\n {}", loggerName,
					msg, loggerTime, getExceptionTrace(e));
		}
	}

	// 返回任务号 TaskNo规则：yyMMdd+接口名称缩写4+随机字符6+MD5计算校验码4 =20位
	public static String getTaskNo(String interfaceName) {
		String str = interfaceName + "_" + DateFormatUtils.format(new Date(), "yyyyMMdd") + "_"
				+ RandomStringUtils.randomAlphanumeric(6);
		return str + MD5(str).substring(0, 4);
	}

	// 生成softId
	public static String creatSoftId(String softName) {
		return MD5(softName + System.currentTimeMillis());
	}

	// 检查任务号-最后4位为校验位
	public static boolean isTaskNo(String taskNo) {
		if (StringUtils.isBlank(taskNo)) {
			return false;
		}
		String startStr = taskNo.substring(0, taskNo.length() - 4);
		String lastStr = taskNo.substring(taskNo.length() - 4);
		String md5Str = MD5(startStr).substring(0, 4);
		if (lastStr.equals(md5Str)) {
			return true;
		}
		return false;
	}

	// MD5摘要
	public static String MD5(String sourceStr) {
		String result = "";
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(sourceStr.getBytes());
			byte b[] = md.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			result = buf.toString();
		} catch (NoSuchAlgorithmException e) {
			System.out.println(e);
		}
		return result;
	}

	// 是否手机号
	public static boolean isMobile(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "(^1\\d{10}$)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	// 是否邮箱格式
	public static boolean isEmail(String str) {
		if (StringUtils.isBlank(str))
			return false;
		String regex = "^(\\w-*\\.*)+@(\\w-?)+(\\.\\w{2,})+$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	// 验证是否18位身份证号
	public static boolean isIdCard18(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "(^\\d{18}$)|(^\\d{17}[Xx]$)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		boolean flag = false;
		if (matcher.matches()) {
			String oVerifyBit = str.substring(17);
			String nVerifyBit = getVerifyBit(str.substring(0, 17));
			Calendar cal = Calendar.getInstance();
			int sysYear = cal.get(Calendar.YEAR);
			int year = Integer.parseInt(str.substring(6, 10));
			int month = Integer.parseInt(str.substring(10, 12));
			int day = Integer.parseInt(str.substring(12, 14));
			if (year >= (sysYear - INTERVAL) && year <= sysYear && month > 0 && month < 13 && day > 0 && day < 32
					&& StringUtils.equalsIgnoreCase(oVerifyBit, nVerifyBit)) {
				flag = true;
			}
		}
		return flag;
	}

	/**
	 * 获取18位身份证的校验位
	 * 
	 * @param str 身份证前17位
	 * @return 结果
	 */
	private static final int[] WI = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
	private static final String[] VI = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" };
	private static final int INTERVAL = 120;

	private static String getVerifyBit(String str) {
		if (StringUtils.isBlank(str) || str.length() != 17)
			return null;
		int[] ai = new int[str.length()];
		for (int i = 0; i < str.length(); i++) {
			ai[i] = Integer.parseInt(str.substring(i, i + 1));
		}
		int num = 0;
		for (int i = 0; i < 17; i++) {
			num += ai[i] * WI[i];
		}
		int remaining = num % 11;
		return VI[remaining];
	}

	/**
	 * 字符串大小写转换 默认大写
	 * 
	 * @param str
	 * @param toLowerCase true则小写转换
	 * @return
	 */
	public static String strCaseConvert(String str, boolean toLowerCase) {
		if (StringUtils.isBlank(str)) {
			return null;
		}

		if (toLowerCase == true) {
			return str.toLowerCase();
		}
		return str.toUpperCase();
	}

	public static String strToUpperCase(String str) {
		return strCaseConvert(str, false);
	}

	/*
	 * 向文件中写入内容
	 */
	public static void writeToFile(String text, String path, boolean append) throws IOException {
		File file = new File(path);
		if (!file.exists()) {
			autoMkDir(path);
		}
		FileWriterWithEncoding fw = new FileWriterWithEncoding(file, "UTF-8", append);// fales不追加 true 追加
		fw.write(text);
		fw.flush();
		fw.close();
	}

	/*
	 * 判断文件是否存在
	 */
	public static boolean isExistFile(String path) {
		File file = new File(path);
		if (file.exists()) {
			return true;
		} else {
			return false;
		}
	}

	// 判断是否是IP地址
	public static boolean isIpV4(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	// 判断是否中文
	public static boolean isChinese(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "^[\u2E80-\u9FFF]+$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	// 判断是否是姓名（2-20个汉字）
	public static boolean isName(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "^[\u2E80-\u9FFF]{1,20}[·.]{0,1}[\u2E80-\u9FFF]{1,20}$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	// 判断是否全部数字
	public static boolean isAllNum(String str) {
		if (StringUtils.isEmpty(str))
			return false;
		String regex = "^\\d+$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	// 计算相差的秒数
	public static int calcCostSeconds(Date beginTime) {
		if (beginTime == null) {
			return -1;
		}
		return (int) (System.currentTimeMillis() - beginTime.getTime()) / 1000;
	}

	/**
	 * 以行为单位读取文件，常用于读面向行的格式化文件，一次读一整行
	 */
	public static String readByLinesToString(String filePath, String charsetName) {
		if (StringUtils.isBlank(filePath)) {
			return null;
		}
		if (StringUtils.isBlank(charsetName)) {
			charsetName = "UTF-8";
		}
		File file = new File(filePath);
		BufferedReader reader = null;
		try {
			InputStreamReader isr = new InputStreamReader(new FileInputStream(file), charsetName);
			reader = new BufferedReader(isr);

			StringBuffer sbf = new StringBuffer();
			String tempString = null;
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				sbf.append(tempString + "\n");
			}
			reader.close();
			return sbf.toString();
		} catch (IOException e) {
			logger.error("读取文件异常：" + CommonUtil.getExceptionTrace(e));
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}

		return null;
	}

	// Date 转 String
	public static String formatDate(Date date, String format) {
		return DateFormatUtils.format(date, format);
	}

	// String转Date
	public static Date parseStrToDate(String dateStr, String format) {
		Date date = null;
		try {
			date = DateUtils.parseDate(dateStr, new String[] { format });
		} catch (Exception e) {
			// 转换异常
		}
		return date;
	}

	// 月份String偏移，如输入"201411","yyyyMM",5 -->"201504"
	public static String monthStringAmount(String monthStr, String format, int amount) {
		// String转date
		Date date = parseStrToDate(monthStr, format);

		// date偏移
		date = DateUtils.addMonths(date, amount);

		// date转String
		return DateFormatUtils.format(date, format);
	}

	/* 用正则表达式匹配是否是数字 */
	public static boolean isNumber(String str) {
		Pattern pattern = Pattern.compile("^[0-9]*$");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * double转换
	 * 
	 * @param doubleStr
	 * @return
	 */
	public static double parseDouble(String doubleStr) {
		double res = 0;
		try {
			res = Double.parseDouble(doubleStr);
		} catch (Exception e) {
			// 转换失败
		}

		return res;
	}

	/**
	 * 字符串是否是日期
	 * 
	 * @author 沈尚玉
	 * @date 2015-7-28
	 * @param strDate 日期字符串
	 * @param format  日期格式
	 * @return true:是, false:否
	 */
	public static boolean isDate(String strDate, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			sdf.setLenient(false);
			sdf.parse(strDate);
		} catch (ParseException e) {
			return false;
		}
		return true;
	}

	/**
	 * 根据日期判断是否需要抓取月份 --yyyyMM 最低抓取range个月，且包含当前月，比如201602-201608
	 * 
	 * @param yyyyMM 传入日期
	 * @param range  判断月份范围
	 * @return
	 */
	public static boolean isCrawlerDate(String yyyyMM, int range) {
		try {
			Date date = DateUtils.parseDate(yyyyMM, new String[] { "yyyyMM" });
			Date today = new Date();
			if (today.after(date) && today.before(DateUtils.addMonths(date, range + 1))) {
				return true;
			}
		} catch (ParseException e) {
			return false;
		}
		return false;
	}

	// 移除&nbsp;的空格
	public static String removeNbsp(String str) {
		if (StringUtils.isNotBlank(str)) {
			return str.replaceAll(" ", "");
		}
		return null;
	}

	// 移除无效字符如各种空格
	public static String removeInvalidStr(String str) {
		if (StringUtils.isNotBlank(str)) {
			return str.replaceAll(" ", "").replaceAll("　", "").replaceAll("\\s*", "");
		}
		return null;
	}

	// 从html中找到指定的变量所在的最近一行
	public static String getFirstLineFromHtml(String targetStr, String htmlStr) {
		if (StringUtils.isBlank(htmlStr)) {
			return null;
		}
		String[] arrays = htmlStr.split("\n");
		for (String str : arrays) {
			if (str.contains(targetStr)) {
				return str;
			}
		}

		return null;
	}

	// 从文档中找到指定的变量所在的最后一行
	public static String getLastLineFromHtml(String targetStr, String htmlStr) {
		if (StringUtils.isBlank(htmlStr)) {
			return null;
		}
		String[] arrays = htmlStr.split("\n");

		for (int i = arrays.length - 1; i >= 0; i--) {
			if (arrays[i].contains(targetStr)) {
				return arrays[i];
			}
		}
		return null;
	}

	// 从html中找到指定的变量所在的行 的集合
	public static List<String> getLineListFromHtml(String targetStr, String htmlStr) {
		if (StringUtils.isBlank(htmlStr)) {
			return null;
		}
		List<String> list = new ArrayList<String>();
		String[] arrays = htmlStr.split("\n");
		for (int i = 0; i < arrays.length; i++) {
			if (arrays[i].contains(targetStr)) {
				list.add(arrays[i]);
			}
		}
		return list;
	}

	/**
	 * 控制台输入数据 @Title: consoleScanner @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @return 参数 @return String 返回类型 @throws
	 */
	@SuppressWarnings("resource")
	public static String consoleScanner() {
		logger.info("---------请准备键盘按键输入内容-----------");
		Scanner scan = new Scanner(System.in);
		String readIn = scan.nextLine();
		logger.info("----------读取键盘输入内容成功，输入数据为：{}", readIn);

		return readIn;
	}

	/**
	 * 生成图片的相对路径 @Title: createFilePath @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param type @param @return 参数 @return String
	 * 返回类型 @throws
	 */
	public static String createFilePath(String type) {
		String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd");
		String imgPath = TempFilePath + "/" + type + "/" + date + "/" + CommonUtil.getTransNo("img") + ".png";
		return imgPath;
	}

	/*
	 * 将时间戳转换为时间字符串
	 */
	public static String timeStampToDateStr(String s, String format) {
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		long lt = new Long(s + "000");
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}

	/**
	 * 根据文件路径，自动判断是否需要创建一个新的目录
	 * 
	 * @param filePath 需要创建的文件完整路径
	 * @return boolean
	 */
	public static boolean autoMkDir(String filePath) {
		boolean blnExist = false;
		String folderPath = "";
		if (filePath.indexOf("/") > 0) {
			folderPath = filePath.substring(0, filePath.lastIndexOf("/"));

		} else if (filePath.indexOf("\\") > 0) {
			folderPath = filePath.substring(0, filePath.lastIndexOf("\\"));
		}
		File file = new File(folderPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		blnExist = file.exists();
		return blnExist;
	}

	/**
	 * 向文件中写入 @Title: writeByteArrayToFile @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param byteArray @param @param
	 * path @param @throws IOException 参数 @return void 返回类型 @throws
	 */
	public static void writeByteArrayToFile(byte[] byteArray, String path, boolean append) throws IOException {
		File file = new File(path);
		if (!file.exists()) {
			autoMkDir(path);
		}
		FileUtils.writeByteArrayToFile(file, byteArray, append);
	}

	/**
	 * 向文件写入内容不追加 @Title: writeByteArrayToFile @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param byteArray @param @param
	 * path @param @throws IOException 参数 @return void 返回类型 @throws
	 */
	public static void writeByteArrayToFile(byte[] byteArray, String path) throws IOException {
		writeByteArrayToFile(byteArray, path, false);
	}

	/**
	 * 字符串转int @Title: stringToInt @Description: TODO(这里用一句话描述这个方法的作用) @param @param
	 * intStr @param @return 参数 @return int 返回类型 @throws
	 */
	public static int stringToInt(String intStr) {
		try {
			return Integer.parseInt(intStr);
		} catch (Exception e) {
			logger.error("------stringToInt 异常----转换字符串为 intStr = {}", intStr);
		}

		return -1;
	}

	/**
	 * 从url中获取指定信息 @Title: getParamFromUrl @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param key @param @param url @param @return
	 * 参数 @return String 返回类型 @throws
	 */
	public static String getParamFromUrl(String key, String url) {

		if (StringUtils.isBlank(url)) {
			return "";
		}

		Map<String, String> map = new HashMap<String, String>();

		if (url.contains("?") && url.split("[?]").length > 1) {
			url = url.split("[?]")[1];
		}

		if (url.contains("&")) {
			String[] kvs = url.split("&");

			for (String kv : kvs) {
				if (kv.contains("=") && kv.split("=").length > 1) {
					map.put(kv.split("=")[0], kv.split("=")[1]);
				}
			}
		} else if (url.contains("=")) {
			map.put(url.split("=")[0], url.split("=")[1]);
		}

		logger.info("----处理后参数列表 map = {}", JSON.toJSONString(map));

		return map.get(key);
	}

	/**
	 * 根据渠道id计算 加密key @Title: calcSecretKeyByChannelId @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param channelId @param @return 参数 @return
	 * String 返回类型 @throws
	 */
	public static String calcSecretKeyByChannelId(String channelId) {
		String secretKey = "";
		if (StringUtils.isBlank(channelId)) {
			logger.info("----channelId 为空---");
			return secretKey;
		}
		secretKey = CommonUtil.MD5(CommonUtil.MD5(channelId + "SIGN") + "$Hj6DXy9k^B#");
		logger.debug("----secretKey = {}", secretKey);
		return secretKey;
	}

	/**
	 * 检测以“，”为分分隔的字符串中是否包含某字符串 @Title: isContain @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param strList @param @param str @param @return
	 * 参数 @return boolean 返回类型 @throws
	 */
	public static boolean isContain(String strList, String str) {
		if (StringUtils.isBlank(strList) || StringUtils.isBlank(strList)) {
			return false;
		} else if (("," + strList + ",").contains("," + str + ",")) {
			return true;
		} else if ("*".equals(strList))// *表示允许任意
		{
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 过滤日期字符 @Title: processDate @Description: TODO(这里用一句话描述这个方法的作用) @param @param
	 * date @param @return 参数 @return String 返回类型 @throws
	 */
	public static String processDate(String date) {
		String s = "";
		if (date != null) {
			s = date.trim().replaceAll("-", "");
			s = s.replaceAll("：", "");
			s = s.replaceAll("/", "");
			s = s.replaceAll("年", "");
			s = s.replaceAll("月", "");
			s = s.replaceAll("日", "");
			if (s.length() < 8) {
				s = s + "01";
			}
		}
		return s;
	}

	/**
	 * 线程睡眠
	 * 
	 * @param millis
	 */
	public static void sleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			// e.printStackTrace();
		}
	}

	/**
	 * 生成otp 一次性密码 规则：使用 uuid +时间 +干扰因素 共同生成
	 * 
	 * @param factor 干扰因素 如ip 指纹等
	 * @return
	 */
	public static String generateOtpKey(String factor) {
		if (StringUtils.isBlank(factor))
			return null;
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		String date = DateFormatUtils.format(new Date(), "yyyyMMddHH");
		String md5uuid = CommonUtil.MD5(date + factor) + uuid;
		String otpkey = md5uuid + CommonUtil.MD5(md5uuid + factor);
		return otpkey;
	}

	/**
	 * 验证opt 一次性密码
	 * 
	 * @param otpkey
	 * @param factor 干扰因素 如ip 指纹等
	 * @return
	 */
	public static boolean checkOtpKey(String otpkey, String factor) {
		if (StringUtils.isBlank(otpkey) || StringUtils.isBlank(factor))
			return false;
		String date = DateFormatUtils.format(new Date(), "yyyyMMddHH");
		String md5datefactor = CommonUtil.MD5(date + factor);
		String firstStr = otpkey.substring(0, otpkey.length() - 32);
		String lastStr = otpkey.substring(otpkey.length() - 32, otpkey.length());
		String checkStr = CommonUtil.MD5(firstStr + factor);
		if (!otpkey.startsWith(md5datefactor) || !StringUtils.equals(checkStr, lastStr))
			return false;
		return true;
	}

	/**
	 * 删除系统日志
	 * 
	 * @param logPath
	 * @param retainDays
	 */
	public static void deleteSystemLog(String logPath, int retainDays) {
		try {
			if (StringUtils.isBlank(logPath))
				return;
			String folderPath = "";
			if (logPath.indexOf("/") >= 0) {
				folderPath = logPath.substring(0, logPath.lastIndexOf("/"));
			} else if (logPath.indexOf("\\") >= 0) {
				folderPath = logPath.substring(0, logPath.lastIndexOf("\\"));
			}
			String filePrefix = logPath.replace(folderPath, "").replace("\\", "").replace("/", "");
			System.out.println(folderPath);
			System.out.println(filePrefix);
			File folder = new File(folderPath);
			if (!folder.exists())
				return;
			Collection<File> listFiles = FileUtils.listFiles(folder, new String[] { "gz" }, false);
			for (File file : listFiles) {
				String fileName = file.getName();
				if (!fileName.startsWith(filePrefix))
					continue;
				// 文件最后修改时间
				Date lastModifiedDate = new Date(file.lastModified());
				// 删除截止日期
				Date deleteDate = DateUtils.addDays(new Date(), -1 * retainDays);
				// 如果在保留日期之前 则删除
				if (lastModifiedDate.before(deleteDate))
					FileUtils.deleteQuietly(file);
			}
		} catch (Exception e) {
			logger.error("----deleteSystemLog error ：{}", CommonUtil.getExceptionTrace(e));
		}
	}

	public static void main(String[] args) {
//    	String key = generateOtpKey("127.0.0.1");
//    	System.out.println(key+"----"+key.length());
//    	System.out.println(checkOtpKey(key, "127.0.0.1"));

	}
}
